package conf_table_define

import (
	"go-iot-gateway/internal/apk/binarys"
	"strconv"
)

const (
	DATA_TYPE_BIT     = "bit"
	DATA_TYPE_UINT8   = "uint8"
	DATA_TYPE_INT8    = "int8"
	DATA_TYPE_INT16   = "int16"
	DATA_TYPE_UINT16  = "uint16"
	DATA_TYPE_INT32   = "int32"
	DATA_TYPE_UINT32  = "uint32"
	DATA_TYPE_BCD16   = "bcd16" //（Binary-Coded Decimal）其中每个十进制数字（0到9）用4位二进制表示
	DATA_TYPE_BCD32   = "bcd32"
	DATA_TYPE_INT64   = "int64"
	DATA_TYPE_UINT64  = "uint64"
	DATA_TYPE_FLOAT32 = "float32"
	DATA_TYPE_FLOAT64 = "float64"
	DATA_TYPE_STRING  = "string"
)

const (
	BIT     = 0
	UINT8   = 1
	INT8    = 2
	UINT16  = 3
	INT16   = 4
	UINT32  = 5
	INT32   = 6
	BCD16   = 7
	BCD32   = 8
	FLOAT32 = 9
	FLOAT64 = 10
	UINT64  = 11
	INT64   = 12
	STRING  = 13
)

const (
	TAG_TYPE_YC = iota //遥测
	TAG_TYPE_YX        //遥信
	TAG_TYPE_YM        //遥脉
	TAG_TYPE_YK        //遥控
	TAG_TYPE_YT        //遥调
)

// TagInfo 数据标签信息
type TagInfo struct {
	Id             int
	Tag_descYcxmkt string
	Tag_reserve    int //-1 系统保留 ， 1 取反
	Tag_id         string
	Tag_name       string  //名称
	Tag_desc       string  //测点描述
	Tag_type       int     //0 yc | 1 yx | 2 ym | 3 yk | 4yt
	Tag_RW         int     //0 只读 | 1 读写 | 2 只写
	Tag_init       float32 //初始值
	Tag_K          float32 //系数K
	Tag_B          float32 //偏移B
	Collect_type   int     //功能码 1 ，2 ，3 ，4 | 98 计算  |  99 设备通讯中断
	Obj_addr       string  //对象地址
	Obj_addr_int   int64   //对象地址 int 类型
	Assist_param   string
	Tag_group      string //分组
	Data_type      int    //数据类型
	Data_format    int    //高低位顺序
	Enable_trans   int
	Org_read_value int
	Trans_value    int
	Enable_bit     int    //按位取
	Start_bit      uint32 //取值位起始位
	End_bit        uint32 //取值终止位
	//Dev_id            string
	Enable_alarm      int //告警使能
	Hh_enable_alarm   int
	H_enable_alarm    int
	L_enable_alarm    int
	Ll_enable_alarm   int
	Hh_alarm_limit    int
	H_alarm_limit     float32
	L_alarm_limit     float32
	Ll_alarm_limit    float32
	Hh_alarm_msg      string
	H_alarm_msg       string
	L_alarm_msg       string
	Ll_alarm_msg      string
	Alarm_dead_area   float32
	Kg_change_mode    int
	Kg_alarm_msg      string
	Alarm_level       int
	Enable_his_save   int
	His_save_type     int
	His_save_interval int
	His_comp_perc     float32
	Is_upload         int
	Pv_flag           int
	Tag_source        int
	Tag_unit          string
	Rev2              string
	Rev3              string
	Rev4              string
	Ori_tag_id        string //原节点，转发节点
	Tag_id_f          int
	Tag_id_h          int
	W_value_f         string
	W_value_h         string
	DeviceInfo        *DeviceInfo
}

// IsSysReserve 是否系统保留
func (t *TagInfo) IsSysReserve() bool {
	return t.Tag_reserve == -1
}

// IsInvert 是否取反
func (t *TagInfo) IsInvert() bool {
	return t.Tag_reserve == 1
}

func (t *TagInfo) IsYc() bool {
	return t.Tag_type == 0
}

func (t *TagInfo) IsYx() bool {
	return t.Tag_type == 1
}

func (t *TagInfo) IsYm() bool {
	return t.Tag_type == 2
}

func (t *TagInfo) IsYk() bool {
	return t.Tag_type == 3
}

func (t *TagInfo) IsYt() bool {
	return t.Tag_type == 4
}

// IsComputeCollect 是否是计算节点
func (t *TagInfo) IsComputeCollect() bool {
	return t.Collect_type == 98
}

// CanRead 是否能读
func (t *TagInfo) CanRead() bool {
	//0 只读 | 1 读写 | 2 只写
	if t.Tag_RW == 0 || t.Tag_RW == 1 {
		return true
	}
	return false
}

// CanWrite 是否能写
func (t *TagInfo) CanWrite() bool {
	//0 只读 | 1 读写 | 2 只写
	if t.Tag_RW == 2 || t.Tag_RW == 1 {
		return true
	}
	return false
}

// EnableBit 是否按值取值
func (t *TagInfo) EnableBit() bool {
	return t.Enable_bit == 1
}

// ByteSize 的数据值
func (t *TagInfo) ByteSize() int {
	switch t.Data_type {
	case BIT: //0  位
		return 1
	case UINT8: //1  8位无符号
		return 1
	case INT8: //2  8位有符号
		return 1
	case UINT16: //3  16位无符号
		return 2
	case INT16: //4  16位有符号
		return 2
	case UINT32: //5  32位无符号
		return 4
	case INT32: //6  32位有符号
		return 4
	case BCD16: //7  16位BCD
		return 2
	case BCD32: //8  32位BCD
		return 4
	case FLOAT32: //9  单精度浮点数
		return 4
	case FLOAT64: //10 双精度浮点数
		return 8
	case UINT64: //11 64位无符号
		return 8
	case INT64: //12 64位有符号
		return 8
	case STRING: //13 字符串
		return 8
	}
	return 8
}

// IsIntAddr 是不是一个整数地址
func (t *TagInfo) IsIntAddr() bool {
	if _, err := strconv.ParseInt(t.Obj_addr, 10, 64); err == nil {
		return true
	}
	return false
}

// DataFormatStr 字节大小端序列化
func (t *TagInfo) DataFormatStr() string {
	return ToStrDataFormat(t.Data_format)
}

// DataTypeStr 数据类型
func (t *TagInfo) DataTypeStr() string {
	return ToStrDataType(t.Data_type)
}

// IsUintData 是否是无符号整型: bit  uint8  uint16  uint32  uint64
func (t *TagInfo) IsUintData() bool {
	switch t.Data_type {
	case BIT, UINT8, UINT16, UINT32, UINT64, BCD16, BCD32:
		return true
	}
	return false
}

// IsBcdData 是否是BCD类型:  BCD16  BCD32
func (t *TagInfo) IsBcdData() bool {
	switch t.Data_type {
	case BCD16, BCD32:
		return true
	}
	return false
}

// IsStringData 是否是字符串
func (t *TagInfo) IsStringData() bool {
	return t.Data_type == STRING
}

// IsIntData 是否整型： int8  int16  int32  int64
func (t *TagInfo) IsIntData() bool {
	switch t.Data_type {
	case INT8, INT16, INT32, INT64:
		return true
	}
	return false
}

// IsFloatData 是否浮点类型： float32  float64
func (t *TagInfo) IsFloatData() bool {
	switch t.Data_type {
	case FLOAT32, FLOAT64:
		return true
	}
	return false
}

func ToStrDataFormat(format int) string {
	switch format {
	case 0:
		return binarys.BYTE_FORMAT_12
	case 1:
		return binarys.BYTE_FORMAT_21
	case 2:
		return binarys.BYTE_FORMAT_1234
	case 3:
		return binarys.BYTE_FORMAT_2143
	case 4:
		return binarys.BYTE_FORMAT_3412
	case 5:
		return binarys.BYTE_FORMAT_4321
	}
	return binarys.BYTE_FORMAT_1234
}

func ToStrDataType(t int) string {
	switch t {
	case BIT: //0  位
		return DATA_TYPE_BIT
	case UINT8: //1  8位无符号
		return DATA_TYPE_UINT8
	case INT8: //2  8位有符号
		return DATA_TYPE_INT8
	case UINT16: //3  16位无符号
		return DATA_TYPE_UINT16
	case INT16: //4  16位有符号
		return DATA_TYPE_INT16
	case UINT32: //5  32位无符号
		return DATA_TYPE_UINT32
	case INT32: //6  32位有符号
		return DATA_TYPE_INT32
	case BCD16: //7  16位BCD
		return DATA_TYPE_BCD16
	case BCD32: //8  32位BCD
		return DATA_TYPE_BCD32
	case FLOAT32: //9  单精度浮点数
		return DATA_TYPE_FLOAT32
	case FLOAT64: //10 双精度浮点数
		return DATA_TYPE_FLOAT64
	case UINT64: //11 64位无符号
		return DATA_TYPE_UINT64
	case INT64: //12 64位有符号
		return DATA_TYPE_INT64
	case STRING: //13 字符串
		return DATA_TYPE_STRING
	}
	return DATA_TYPE_FLOAT64
}
